#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@file config.py
@author weiximei
@date 2025/3/5 15:49
"""
import yaml
from dacite import from_dict, Config

from config.app import AppConfig
from internal.errors import YqmError
from internal.utils import path_utils


# 递归合并配置
def deep_merge(base: dict, override: dict) -> dict:
    for key, value in override.items():
        if key in base and isinstance(base[key], dict) and isinstance(value, dict):
            deep_merge(base[key], value)
        else:
            base[key] = value
    return base


# 加载配置文件
def load_config(env: str = '') -> AppConfig:
    """
    加载配置文件
    Args:
        env: 环境名称
    Returns:
        AppConfig: 配置对象
    Raises:
        FileNotFoundError: 配置文件不存在时抛出
        yaml.YAMLError: YAML解析错误时抛出
    """

    if env is None or env == '':
        raise YqmError(code=500, message='环境变量 ENV 未设置')

    resource_path = path_utils.getResourcesPath()
    base_application_yml = f'application.yml'
    env_application_yml = f'application-{env}.yml'
    path_base_str = f'{resource_path}/{base_application_yml}'
    path_str = f'{resource_path}/{env_application_yml}'

    try:
        with open(path_base_str, 'r', encoding='utf-8') as f:
            base_config_dict = yaml.safe_load(f)

        try:
            with open(path_str, 'r', encoding='utf-8') as f:
                config_dict = yaml.safe_load(f)
                if config_dict:
                    base_config_dict = deep_merge(base_config_dict, config_dict)
        except FileNotFoundError:
            print(f"警告: 环境配置文件 {env_application_yml} 不存在，将使用基础配置")

        return from_dict(
            data_class=AppConfig,
            data=base_config_dict,
            config=Config(
                check_types=True,
                strict=False,  # 严格模式 为 false
                cast=[int, str]  # 允许类型转换
            )
        )
    except FileNotFoundError as e:
        raise FileNotFoundError(f"配置文件不存在: {e.filename}") from e
    except yaml.YAMLError as e:
        raise yaml.YAMLError(f"YAML解析错误: {str(e)}") from e
